package permhelp

import (
	"fmt"
	"github.com/astaxie/beego/orm"
	"io/ioutil"
)

//对比两个数据库t_perm 生成差异sql
type RemotePermHelp struct {
	DstPerms    []Perm //目标数据库权限
	DstPermsMap map[string]Perm

	SrcPerms    []Perm //本地数据库权限
	SrcPermsMap map[string]Perm
}

//远程数据权限自动生成
func NewRemotePermHelp() *RemotePermHelp {
	this := &RemotePermHelp{
		DstPermsMap: make(map[string]Perm),
		SrcPermsMap: make(map[string]Perm),
	}
	this.initPermData().checkId()

	return this
}

//初始化数据
func (this *RemotePermHelp) initPermData() *RemotePermHelp {

	Orm := orm.NewOrm()
	if _, err := Orm.QueryTable(PermTableName).Limit(-1).All(&this.SrcPerms); err != nil {
		panic(err)
	}

	for _, v := range this.SrcPerms {
		this.SrcPermsMap[v.PermUrl] = v
	}

	if err := Orm.Using("dst"); err != nil {
		panic(err)
	}

	if _, err := Orm.QueryTable(PermTableName).Limit(-1).All(&this.DstPerms); err != nil {
		panic(err)
	}

	for _, v := range this.DstPerms {
		this.DstPermsMap[v.PermUrl] = v
	}

	return this
}

//检查url 和id对应不上的数据
func (this *RemotePermHelp) checkId() *RemotePermHelp {
	for k := range this.SrcPermsMap {
		if perm, ok := this.DstPermsMap[k]; !ok {
			//fmt.Println("本地数据库有，远程没有的权限:",k)
		} else {
			if this.SrcPermsMap[k].Id != perm.Id {
				fmt.Println("本地数据和远程数据ID不一致:", k)
			}
		}
	}

	return this

}

//生成sql
func (this *RemotePermHelp) CreateSql(output string) error {
	fmt.Println("本地数据库权限条数：", len(this.SrcPerms))
	fmt.Println("远程数据库权限条数：", len(this.DstPerms))
	var contentStr string

	for k := range this.SrcPermsMap {
		if _, ok := this.DstPermsMap[k]; !ok {
			//本地数据库有，远程没有的权限
			//插入数据
			contentStr += fmt.Sprintf(SyncInsertSql, this.SrcPermsMap[k].Id, this.SrcPermsMap[k].Name, this.SrcPermsMap[k].PermUrl, this.SrcPermsMap[k].PermtreeId)
		} else {
			//更新数据
			if this.SrcPermsMap[k].Name != this.DstPermsMap[k].Name || this.SrcPermsMap[k].PermtreeId != this.DstPermsMap[k].PermtreeId {
				contentStr += fmt.Sprintf(SyncUpdateSql, this.SrcPermsMap[k].Name, this.SrcPermsMap[k].PermtreeId, this.SrcPermsMap[k].Id)
			}
		}
	}

	return ioutil.WriteFile(output, []byte(contentStr), 0644)

}
